/**
 * 文本输入组件
 */
import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';
import {
    TextInput as RNTextInput,
    View,
    Text,
    StyleSheet,
    StyleProp,
    ViewStyle,
    TextStyle,
    NativeSyntheticEvent,
    TextInputFocusEventData,
    TextInputProps as RNTextInputProps,
    Platform
} from 'react-native';
import theme from '../../styles/theme';
import globalStyles from '../../styles/global';

/**
 * 文本输入组件变体
 */
export type TextInputVariant = 'outlined' | 'filled' | 'underlined';

/**
 * 文本输入组件尺寸
 */
export type TextInputSize = 'small' | 'medium' | 'large';

/**
 * 文本输入组件属性接口
 */
export interface TextInputProps extends Omit<RNTextInputProps, 'style'> {
    /** 输入标签 */
    label?: string;
    /** 是否必填 */
    required?: boolean;
    /** 帮助文本 */
    helperText?: string;
    /** 错误文本 */
    errorText?: string;
    /** 是否有错误 */
    error?: boolean;
    /** 输入框引用 */
    inputRef?: React.RefObject<RNTextInput>;
    /** 组件变体 */
    variant?: TextInputVariant;
    /** 组件尺寸 */
    size?: TextInputSize;
    /** 左侧图标 */
    leftIcon?: React.ReactNode;
    /** 右侧图标 */
    rightIcon?: React.ReactNode;
    /** 容器样式 */
    containerStyle?: StyleProp<ViewStyle>;
    /** 输入框样式 */
    inputStyle?: StyleProp<TextStyle>;
    /** 标签样式 */
    labelStyle?: StyleProp<TextStyle>;
    /** 帮助文本样式 */
    helperTextStyle?: StyleProp<TextStyle>;
    /** 错误文本样式 */
    errorTextStyle?: StyleProp<TextStyle>;
    /** 是否禁用 */
    disabled?: boolean;
    /** 最大字符数 */
    maxLength?: number;
    /** 是否显示字符计数 */
    showCount?: boolean;
    /** 输入框内边距 */
    inputPadding?: number;
    /** 清除按钮 */
    clearButton?: boolean;
    /** 自定义后缀内容 */
    suffix?: React.ReactNode;
    /** 自定义前缀内容 */
    prefix?: React.ReactNode;
    /** 自定义验证函数 */
    validate?: (text: string) => string | null;
}

/**
 * 文本输入引用接口
 */
export interface TextInputRef {
    focus: () => void;
    blur: () => void;
    clear: () => void;
    getValue: () => string;
    setValue: (value: string) => void;
    validate: () => boolean;
}

/**
 * 文本输入组件
 */
const TextInput = forwardRef<TextInputRef, TextInputProps>(({
    label,
    required = false,
    helperText,
    errorText,
    error = false,
    inputRef,
    variant = 'outlined',
    size = 'medium',
    leftIcon,
    rightIcon,
    containerStyle,
    inputStyle,
    labelStyle,
    helperTextStyle,
    errorTextStyle,
    disabled = false,
    maxLength,
    showCount = false,
    inputPadding,
    clearButton = false,
    suffix,
    prefix,
    validate,
    onFocus,
    onBlur,
    value,
    onChangeText,
    placeholder,
    secureTextEntry,
    ...rest
}, ref) => {
    // 状态
    const [isFocused, setIsFocused] = useState(false);
    const [inputValue, setInputValue] = useState(value || '');
    const [validationError, setValidationError] = useState<string | null>(null);

    // 内部引用
    const internalRef = useRef<RNTextInput>(null);

    // 向外部暴露方法
    useImperativeHandle(ref, () => ({
        focus: () => {
            internalRef.current?.focus();
        },
        blur: () => {
            internalRef.current?.blur();
        },
        clear: () => {
            internalRef.current?.clear();
            setInputValue('');
            onChangeText && onChangeText('');
        },
        getValue: () => inputValue,
        setValue: (value: string) => {
            setInputValue(value);
            onChangeText && onChangeText(value);
        },
        validate: () => {
            if (validate) {
                const errorMessage = validate(inputValue);
                setValidationError(errorMessage);
                return !errorMessage;
            }
            return !error;
        }
    }));

    // 处理焦点事件
    const handleFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
        setIsFocused(true);
        onFocus && onFocus(e);
    };

    // 处理失焦事件
    const handleBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
        setIsFocused(false);
        onBlur && onBlur(e);

        // 失焦时验证
        if (validate) {
            const errorMessage = validate(inputValue);
            setValidationError(errorMessage);
        }
    };

    // 处理文本变化
    const handleChangeText = (text: string) => {
        setInputValue(text);
        onChangeText && onChangeText(text);

        // 清除验证错误
        if (validationError) {
            setValidationError(null);
        }
    };

    // 处理清除按钮点击
    const handleClear = () => {
        internalRef.current?.clear();
        setInputValue('');
        onChangeText && onChangeText('');
        internalRef.current?.focus();
    };

    // 是否显示错误
    const hasError = error || !!errorText || !!validationError;

    // 获取容器样式
    const getContainerStyle = (): StyleProp<ViewStyle> => {
        const baseStyle: StyleProp<ViewStyle>[] = [styles.container];

        // 变体样式
        if (variant === 'filled') {
            baseStyle.push(styles.filledContainer);
        } else if (variant === 'underlined') {
            baseStyle.push(styles.underlinedContainer);
        }

        // 尺寸
        baseStyle.push(styles[`${size}Container`]);

        // 禁用状态
        if (disabled) {
            baseStyle.push(styles.disabledContainer);
        }

        return [baseStyle, containerStyle];
    };

    // 获取输入框样式
    const getInputStyle = (): StyleProp<TextStyle> => {
        const baseStyle: StyleProp<TextStyle>[] = [
            styles.input,
            styles[`${size}Input`]
        ];

        // 变体样式
        if (variant === 'filled') {
            baseStyle.push(styles.filledInput);
        } else if (variant === 'underlined') {
            baseStyle.push(styles.underlinedInput);
        }

        // 聚焦状态
        if (isFocused) {
            baseStyle.push(styles.focusedInput);
        }

        // 错误状态
        if (hasError) {
            baseStyle.push(styles.errorInput);
        }

        // 禁用状态
        if (disabled) {
            baseStyle.push(styles.disabledInput);
        }

        // 左侧图标/前缀
        if (leftIcon || prefix) {
            baseStyle.push(styles.inputWithLeftIcon);
        }

        // 右侧图标/后缀
        if (rightIcon || suffix || (clearButton && inputValue)) {
            baseStyle.push(styles.inputWithRightIcon);
        }

        // 自定义内边距
        if (inputPadding !== undefined) {
            baseStyle.push({ padding: inputPadding });
        }

        return [baseStyle, inputStyle];
    };

    // 渲染标签
    const renderLabel = () => {
        if (!label) return null;

        return (
            <Text style={[
                styles.label,
                hasError && styles.errorLabel,
                isFocused && styles.focusedLabel,
                disabled && styles.disabledLabel,
                labelStyle
            ]}>
                {label}{required && <Text style={styles.requiredMark}>*</Text>}
            </Text>
        );
    };

    // 渲染帮助文本或错误文本
    const renderHelper = () => {
        const showError = hasError && (errorText || validationError);
        const showHelper = !showError && helperText;
        const showCounter = showCount && maxLength;

        if (!showError && !showHelper && !showCounter) {
            return null;
        }

        return (
            <View style={styles.helperContainer}>
                {showError && (
                    <Text style={[styles.helperText, styles.errorText, errorTextStyle]}>
                        {errorText || validationError}
                    </Text>
                )}

                {showHelper && (
                    <Text style={[styles.helperText, helperTextStyle]}>
                        {helperText}
                    </Text>
                )}

                {showCounter && (
                    <Text style={[
                        styles.helperText,
                        styles.counter,
                        inputValue.length > maxLength ? styles.errorText : undefined,
                        inputValue.length > maxLength ? errorTextStyle : helperTextStyle
                    ]}>
                        {inputValue.length}/{maxLength}
                    </Text>
                )}
            </View>
        );
    };

    // 渲染输入框
    return (
        <View style={styles.wrapper}>
            {renderLabel()}

            <View style={getContainerStyle()}>
                {leftIcon && <View style={styles.leftIconContainer}>{leftIcon}</View>}
                {prefix && <View style={styles.prefixContainer}>{prefix}</View>}

                <RNTextInput
                    ref={internalRef}
                    style={getInputStyle()}
                    onFocus={handleFocus}
                    onBlur={handleBlur}
                    onChangeText={handleChangeText}
                    value={inputValue}
                    placeholder={placeholder}
                    placeholderTextColor={theme.colors.text.hint}
                    editable={!disabled}
                    maxLength={maxLength}
                    secureTextEntry={secureTextEntry}
                    {...rest}
                />

                {clearButton && inputValue.length > 0 && (
                    <View style={styles.rightIconContainer}>
                        <Text style={styles.clearButton} onPress={handleClear}>✕</Text>
                    </View>
                )}

                {suffix && <View style={styles.suffixContainer}>{suffix}</View>}
                {rightIcon && <View style={styles.rightIconContainer}>{rightIcon}</View>}
            </View>

            {renderHelper()}
        </View>
    );
});

// 样式
const styles = StyleSheet.create({
    wrapper: {
        marginBottom: theme.spacing.md,
    },
    container: {
        ...globalStyles.input,
        flexDirection: 'row',
        alignItems: 'center',
        borderWidth: 1,
        borderColor: theme.colors.gray[300],
        borderRadius: theme.borderRadius.md,
        backgroundColor: theme.colors.background.default,
        paddingVertical: 0,
        paddingHorizontal: 0,
        overflow: 'hidden'
    },
    filledContainer: {
        borderWidth: 0,
        backgroundColor: theme.colors.gray[100],
        borderTopLeftRadius: theme.borderRadius.md,
        borderTopRightRadius: theme.borderRadius.md,
        borderBottomLeftRadius: 0,
        borderBottomRightRadius: 0,
        borderBottomWidth: 2,
        borderBottomColor: theme.colors.gray[400]
    },
    underlinedContainer: {
        borderWidth: 0,
        borderRadius: 0,
        borderBottomWidth: 1,
        borderBottomColor: theme.colors.gray[400],
        paddingLeft: 0,
        paddingRight: 0
    },
    smallContainer: {
        height: 40
    },
    mediumContainer: {
        height: 48
    },
    largeContainer: {
        height: 56
    },
    input: {
        flex: 1,
        fontFamily: theme.typography.fontFamily.base,
        color: theme.colors.text.primary,
        paddingHorizontal: theme.spacing.md,
        paddingVertical: theme.spacing.sm,
        width: '100%',
        ...Platform.select({
            web: {
                outlineStyle: 'none'
            }
        })
    },
    filledInput: {
        paddingTop: theme.spacing.md,
        backgroundColor: 'transparent'
    },
    underlinedInput: {
        paddingLeft: 0,
        paddingRight: 0,
        paddingBottom: theme.spacing.xs
    },
    smallInput: {
        fontSize: theme.typography.fontSize.sm,
        paddingVertical: theme.spacing.xs
    },
    mediumInput: {
        fontSize: theme.typography.fontSize.md
    },
    largeInput: {
        fontSize: theme.typography.fontSize.lg
    },
    inputWithLeftIcon: {
        paddingLeft: 0
    },
    inputWithRightIcon: {
        paddingRight: 0
    },
    focusedInput: {
        borderColor: theme.colors.primary.main
    },
    errorInput: {
        borderColor: theme.colors.error.main
    },
    disabledContainer: {
        backgroundColor: theme.colors.background.disabled,
        borderColor: theme.colors.gray[300],
        opacity: 0.7
    },
    disabledInput: {
        color: theme.colors.text.disabled
    },
    label: {
        fontFamily: theme.typography.fontFamily.base,
        fontSize: theme.typography.fontSize.sm,
        color: theme.colors.text.secondary,
        marginBottom: theme.spacing.xs
    },
    requiredMark: {
        color: theme.colors.error.main,
        marginLeft: 2
    },
    focusedLabel: {
        color: theme.colors.primary.main
    },
    errorLabel: {
        color: theme.colors.error.main
    },
    disabledLabel: {
        color: theme.colors.text.disabled
    },
    leftIconContainer: {
        paddingLeft: theme.spacing.md,
        paddingRight: theme.spacing.xs
    },
    rightIconContainer: {
        paddingRight: theme.spacing.md,
        paddingLeft: theme.spacing.xs
    },
    prefixContainer: {
        paddingLeft: theme.spacing.md
    },
    suffixContainer: {
        paddingRight: theme.spacing.md
    },
    helperContainer: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        marginTop: theme.spacing.xs
    },
    helperText: {
        fontFamily: theme.typography.fontFamily.base,
        fontSize: theme.typography.fontSize.xs,
        color: theme.colors.text.secondary
    },
    errorText: {
        color: theme.colors.error.main
    },
    counter: {
        textAlign: 'right',
        marginLeft: 'auto'
    },
    clearButton: {
        fontSize: theme.typography.fontSize.sm,
        color: theme.colors.gray[500],
        width: 16,
        height: 16,
        textAlign: 'center',
        lineHeight: 16
    }
});

export default TextInput; 